
package com.zdkj.subway.rca.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zdkj.subway.rca.entity.CodeName;
import com.zdkj.subway.rca.entity.SwCkBankCashPaymentNote;
import com.zdkj.subway.rca.enums.SW_CK_BANK_CASH_PAYMENT_NOTE_DATA_TYPE;
import com.zdkj.subway.rca.exceptions.BizException;
import com.zdkj.subway.rca.mapper.SwCkBankCashPaymentNoteMapper;
import com.zdkj.subway.rca.service.SwCkBankCashPaymentNoteService;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Date;
/**
 * 银行现金缴款单
 *
 * @author cooze
 * @date 2020-10-18 17:26:59
 */
@Service
public class SwCkBankCashPaymentNoteServiceImpl extends ServiceImpl<SwCkBankCashPaymentNoteMapper, SwCkBankCashPaymentNote> implements SwCkBankCashPaymentNoteService {


    @Override
    public List<CodeName> listAllSubWayLineByDataType(String dataType) {
        return this.baseMapper.listAllSubWayLine(dataType);
    }

    @Override
    public List<CodeName> listSubWayStationByLineCodeAndDataType(String lineCode, String dataType) {
        return this.baseMapper.listSubWayStationByLineCode(lineCode, dataType);
    }

    @Override
    public boolean save(SwCkBankCashPaymentNote entity) {
        //同一天内，同一条线路、站点，只能有一条交款单
        Integer integer = baseMapper.selectCount(Wrappers.query(entity)
                .lambda().eq(SwCkBankCashPaymentNote::getLineCode, entity.getLineCode())
                .eq(SwCkBankCashPaymentNote::getStationCode, entity.getStationCode())
                .eq(SwCkBankCashPaymentNote::getTradeTime, entity.getTradeTime()));
        if (Objects.nonNull(integer) && integer > 0) {
            throw new BizException("EXIST");
        }
        return super.save(entity);
    }

    @Override
    public SwCkBankCashPaymentNote getUnloadShortAmount(String dataType, String lineCode, String stationCode, String tradeTime) {
        SW_CK_BANK_CASH_PAYMENT_NOTE_DATA_TYPE dt = SW_CK_BANK_CASH_PAYMENT_NOTE_DATA_TYPE.toEnum(dataType).get();
        /*
        补卸载金额（分）
        1.数据类型如果是银行单据数据（非长周期），根据交易日期与钱箱未卸载库表 SW_ST_INPUT_CASHBOX_UNINSTALLED 查找入账日期等于交易日期，
          且是该线路和站点的所有卸载金额（UNINSTALL_AMOUNT）
        2.如果是长周期结算，根据开始日期和结束日期查找时间范围内的钱箱未卸载金额，入账日期是在此时间范围内该线路和站点内的数据之和。

        补短款金额（分）
        1.数据类型如果是银行单据数据（非长周期），根据交易日期，查找车站补款记录中，补款入账日期的该线路和站点补款金额之和。
        2.如果是长周期结算，根据开始日期和结束日期查找时间范围内的补款金额，入账日期是在此时间范围内该线路和站点内的数据之和。
            SW_AU_STATION_SHORT库表的SHORT_AMOUNT字段。
            根据线路、站点、补款日期匹配查找相应补款金额
            SHORT_AMOUNT字段
         */
        SwCkBankCashPaymentNote res = new SwCkBankCashPaymentNote();
        LocalDate tradeTimeLocalDate = LocalDate.parse(tradeTime, DateTimeFormatter.ofPattern("yyyy-MM-dd"));

	      /*
        如果是长周期结算，入账开始日期和结束日期计算规则如下：
       根据sw_pm_long_period_settlement 表中周期指值，
        计算出
       入账开始日期=交易日期-(周期指值 - 1)
        入账结束日期=交易日期
         */
        if (dt.equals(SW_CK_BANK_CASH_PAYMENT_NOTE_DATA_TYPE.LONG_CYCLE)) {
            //根据交易日期，从sw_ck_data_submit_log表中查找开始日期和结束日期
			Map<String,Object> map = this.baseMapper.getEntryTime(lineCode,stationCode,tradeTime+" 01:59:59");
            //入账开始日期=交易日期-(周期指值 - 1)
            //Integer balanceDate = baseMapper.getBalanceDate(lineCode, stationCode);
            //res.setEntryStartTime( tradeTimeLocalDate.minusDays(balanceDate - 1));
            
			res.setEntryStartTime(map.get("BEGIN_TIME")==null?tradeTimeLocalDate:LocalDate.parse((String)map.get("BEGIN_TIME")));
            //入账结束日期=交易日期
            //res.setEntryEndTime(tradeTimeLocalDate);
			res.setEntryEndTime(map.get("END_TIME")==null?tradeTimeLocalDate:LocalDate.parse((String)map.get("END_TIME")));
        } else {
            res.setEntryStartTime(tradeTimeLocalDate);
            res.setEntryEndTime(tradeTimeLocalDate);
        }

        /*
                从收入审核-车站钱箱未卸载审核-取得，TVM补卸载金额
                根据记账日期和交易日期进行关联
                根据线路、站点、入账日期查找所有钱箱的卸载金额之和sw_st_input_cashbox_uninstalled（需要增加一个字段，入账日期 POST_DATE  date  yyyy-MM-dd）
                 */
        SwCkBankCashPaymentNote unloadAmount = this.baseMapper.getSupUnloadAmount(res.getEntryStartTime(), res.getEntryEndTime(), lineCode, stationCode);

        /*
             两种补款金额之和：
             收入审核-车站票款差异补款
             根据线路、站点、入账日期匹配查找相应短款金额
             2-2-28、车站票款短款 SW_AU_STATION_SHORT
             补款状态为已补款（ACCOUNT_TIME）入账日期和交易日期对比

             收入审核-售票员补款
             根据线路、站点、入账日期匹配查找相应补款金额
             SW_AU_CONDUCTOR_SHORT 表补款状态为已补款（ACCOUNT_TIME）入账日期和交易日期对比

             在SQL中union all 完成计算
        */
        SwCkBankCashPaymentNote supShortAmount = baseMapper.getSupShortAmount(res.getEntryStartTime(), res.getEntryEndTime(), lineCode, stationCode);
        res.setSupUnloadAmount(Objects.isNull(unloadAmount) ? new BigDecimal("0") : unloadAmount.getSupUnloadAmount());
        res.setSupShortAmount(Objects.isNull(supShortAmount) ? new BigDecimal("0") : supShortAmount.getSupShortAmount());


        return res;
    }


    @Override
    public List<Map<String,Object>> getSwStReportqueryStationincomeList(String startDate, String endDate) {
        return baseMapper.getSwStReportqueryStationincomeList(startDate,endDate);
    }
    @Override
    public IPage<SwCkBankCashPaymentNote> getSwCkBankCashPaymentNote(IPage page, String lineCode, String stationCode, String startDate, String endDate,String tradeTime,String executeStatus,String diffCondition) {
        return baseMapper.getSwCkBankCashPaymentNote(page,lineCode,stationCode,startDate,endDate,tradeTime,executeStatus,diffCondition);
    }

    @Override
    public boolean updateExecuteStatus(LocalDate startDateLocalDate, LocalDate endDateLocalDate) {
        return baseMapper.updateExecuteStatus(startDateLocalDate,endDateLocalDate);
    }

}
